package com.xmtlxx.web.controller.system;


import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpUtil;
import com.xmtlxx.common.annotation.Log;
import com.xmtlxx.common.core.controller.BaseController;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.domain.R;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.core.validate.QueryGroup;
import com.xmtlxx.common.enums.BusinessType;
import com.xmtlxx.common.exception.ServiceException;
import com.xmtlxx.common.helper.LoginHelper;
import com.xmtlxx.common.utils.BarCodeUtil;
import com.xmtlxx.common.utils.DateUtils;
import com.xmtlxx.common.utils.QRCodeUtil;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.common.utils.file.FileUtils;
import com.xmtlxx.system.domain.SysOss;
import com.xmtlxx.system.domain.bo.SysOssBo;
import com.xmtlxx.system.domain.vo.SysOssVo;
import com.xmtlxx.system.service.ISysConfigService;
import com.xmtlxx.system.service.ISysOssService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 文件上传 控制层
 *
 * @author xmtlxx
 */
@Validated
@Api(value = "对象存储控制器", tags = {"对象存储管理"})
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/oss")
public class SysOssController extends BaseController {

    private final ISysOssService iSysOssService;
    private final ISysConfigService iSysConfigService;

    /**
     * 查询OSS对象存储列表
     */
    @ApiOperation("查询OSS对象存储列表")
//    @SaCheckPermission("system:oss:list")
    @GetMapping("/list")
    public TableDataInfo<SysOssVo> list(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) {
        return iSysOssService.queryPageList(bo, pageQuery);
    }

    /**
     * 查询OSS对象存储列表
     */
    @ApiOperation("查询OSS对象存储列表")
//    @SaCheckPermission("system:oss:list")
    @GetMapping("/listoss")
    public R<List<SysOss>> listoss(@Validated(QueryGroup.class) SysOssBo bo, PageQuery pageQuery) {
        return R.ok(iSysOssService.selectSysOssList(bo));
    }

    /**
     * 上传OSS对象存储
     */
    @ApiOperation("上传OSS对象存储")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataTypeClass = File.class, required = true)
    })
//    @SaCheckPermission("system:oss:upload")
    @Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
    @PostMapping("/upload")
    public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file,String lng,String lat,String addr,String buss,String objid) {
        if (ObjectUtil.isNull(file)) {
            throw new ServiceException("上传文件不能为空");
        }
        Map<String,Object> params = new HashMap<>();
//        lng = "118.998989";
//        lat = "24.99876878";
//        addr = "福建省厦门市集美区杏林街道宁宝花园文达路21号4梯507室";
        if(StringUtils.isNotBlank(lng) && StringUtils.isNotBlank(lat) && StringUtils.isNotBlank(addr)){
//            String text = "陈荣瑜_01:54_2022.06.06_福建省厦门市集美区杏林街道宁宝花园文达路21号4梯507室_118.998989 24.99876878";
            String text = LoginHelper.getNickname()+"_"
                +DateUtils.date2String(new Date(),"HH:mm")+"_"
                +DateUtils.date2String(new Date(),"yyyy-MM-dd")+"_"
                +addr+"_"
                +lng+" "+lat;
            params.put("mark",1);
            params.put("text",text);
        }

        SysOss oss = iSysOssService.upload(file,params,buss,objid);
        Map<String, String> map = new HashMap<>(2);
        map.put("url", oss.getUrl());
        map.put("fileName", oss.getFileName());
        map.put("originalName", oss.getOriginalName());
        map.put("fileSuffix", oss.getFileSuffix());
        map.put("ossId", oss.getOssId().toString());
        return R.ok(map);
    }

    @ApiOperation("下载OSS对象存储")
    @SaCheckPermission("system:oss:download")
    @GetMapping("/download/{ossId}")
    public void download(@ApiParam("OSS对象ID") @PathVariable Long ossId, HttpServletResponse response) throws IOException {
        SysOss sysOss = iSysOssService.getById(ossId);
        if (ObjectUtil.isNull(sysOss)) {
            throw new ServiceException("文件数据不存在!");
        }
        response.reset();
        FileUtils.setAttachmentResponseHeader(response, sysOss.getOriginalName());
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE + "; charset=UTF-8");
        long data;
        try {
            data = HttpUtil.download(sysOss.getUrl(), response.getOutputStream(), false);
        } catch (HttpException e) {
            if (e.getMessage().contains("403")) {
                throw new ServiceException("无读取权限, 请在对应的OSS开启'公有读'权限!");
            } else {
                throw new ServiceException(e.getMessage());
            }
        }
        response.setContentLength(Convert.toInt(data));
    }

    /**
     * 删除OSS对象存储
     */
    @ApiOperation("删除OSS对象存储")
//    @SaCheckPermission("system:oss:remove")
    @Log(title = "OSS对象存储", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ossIds}")
    public R<Void> remove(@ApiParam("OSS对象ID串")
                                   @NotEmpty(message = "主键不能为空")
                                   @PathVariable Long[] ossIds) {
        return toAjax(iSysOssService.deleteWithValidByIds(Arrays.asList(ossIds), true) ? 1 : 0);
    }

    /**
     * 删除OSS对象存储
     */
    @ApiOperation("删除OSS对象存储")
//    @SaCheckPermission("system:oss:remove")
    @Log(title = "OSS对象存储", businessType = BusinessType.DELETE)
    @PostMapping("/removebyurl")
    public R<Void> removeByUrl(String url) {
        return toAjax(iSysOssService.deleteWithValidByUrl(url) ? 1 : 0);
    }

    /**
     * 根据 content 生成二维码
     */
    @GetMapping(value = "/getQRCode")
    public void getQRCode(HttpServletResponse response,
                          @RequestParam("content") String content,
                          @RequestParam(value = "logoUrl", required = false) String logoUrl) throws Exception {
        ServletOutputStream stream = null;
        try {
            stream = response.getOutputStream();
            QRCodeUtil.getQRCode(content, logoUrl, stream);
        } catch (Exception e) {
            e.getStackTrace();
        } finally {
            if (stream != null) {
                stream.flush();
                stream.close();
            }
        }
    }

    /**
     * 根据 content 生成条形码
     */
    @GetMapping(value = "/getBarCode")
    public void getBarCode(HttpServletResponse response,
                          @RequestParam("content") String content,
                          @RequestParam(value = "words", required = false) String words) throws Exception {
        ServletOutputStream stream = null;
        try {
            stream = response.getOutputStream();
            BarCodeUtil.getBarCode(content,words,stream);
        } catch (Exception e) {
            e.getStackTrace();
        } finally {
            if (stream != null) {
                stream.flush();
                stream.close();
            }
        }
    }

    @ApiOperation("上传图片生成base64")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataTypeClass = File.class, required = true)
    })
    @PostMapping("/uploadFileToBase64")
    public R<Map<String,Object>> uploadFileToBase64(@RequestPart("file") MultipartFile file) {
        if (ObjectUtil.isNull(file)) {
            throw new ServiceException("上传文件不能为空");
        }
        Map<String,Object> params = new HashMap<>();

        if (file == null || file.isEmpty()) {
            throw new RuntimeException("图片不能为空！");
        }
        Map<String,Object> result = new HashMap<>();

        String contentType = file.getContentType();
        byte[] imageBytes = null;
        String base64EncoderImg="";
        try {
            imageBytes = file.getBytes();
            BASE64Encoder base64Encoder =new BASE64Encoder();
            /**
             * 1.Java使用BASE64Encoder 需要添加图片头（"data:" + contentType + ";base64,"），
             *   其中contentType是文件的内容格式。
             * 2.Java中在使用BASE64Enconder().encode()会出现字符串换行问题，这是因为RFC 822中规定，
             *   每72个字符中加一个换行符号，这样会造成在使用base64字符串时出现问题，
             *   所以我们在使用时要先用replaceAll("[\\s*\t\n\r]", "")解决换行的问题。
             */
            base64EncoderImg = "data:" + contentType + ";base64," + base64Encoder.encode(imageBytes);
            base64EncoderImg = base64EncoderImg.replaceAll("[\\s*\t\n\r]", "");
            result.put("img",base64EncoderImg);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new ServiceException("生成打印文件失败！");
        }
        return R.ok(result);
    }

}
